package com.proxy.scanandcheck.scaner.dao;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.apache.log4j.Logger;
import org.junit.Test;
import org.springframework.stereotype.Component;

import com.proxy.scanandcheck.common.util.Constants;
import com.proxy.scanandcheck.common.util.IPUtil;
import com.proxy.scanandcheck.common.util.RandomUtil;
import com.proxy.scanandcheck.common.valueobject.ProxyRequest;
import com.proxy.scanandcheck.scaner.valueobject.IpAddress;
import com.proxy.scanandcheck.scaner.valueobject.StartEndIp;

@Component
public class ScannerDao {
	
	private static final Logger LOGGER = Logger.getLogger(ScannerDao.class);
	
	
	public List<IpAddress> getIpAddressList(ProxyRequest proxyRequest, int startIndex, int endIndex)
	{
		List<IpAddress> result = null;
		if(proxyRequest.getIpClass().equals(ProxyRequest.A_CLASS))
		{
			result = this.getByStartEndIp(ProxyRequest.A_CLASS, Constants.AClassStartIp, Constants.AClassEndIp, startIndex, endIndex);
		}
		else if(proxyRequest.getIpClass().equals(ProxyRequest.B_CLASS))
		{
			result = this.getByStartEndIp(ProxyRequest.B_CLASS, Constants.BClassStartIp, Constants.BClassEndIp, startIndex, endIndex);
		}
		else if(proxyRequest.getIpClass().equals(ProxyRequest.C_CLASS))
		{
			result = this.getByStartEndIp(ProxyRequest.C_CLASS, Constants.CClassStartIp, Constants.CClassEndIp, startIndex, endIndex);
		}
		return result;
	}
	
	private List<IpAddress> getByStartEndIp(String ipClass, String startIpStr, String endIpStr, int startIndex, int endIndex)
	{
		//1.0.0.1-126.255.255.254
		String [] startIp = startIpStr.split("\\.");
		String [] endIp = endIpStr.split("\\.");
		
		int [] startIpint = {Integer.parseInt(startIp[0]),
								Integer.parseInt(startIp[1]),
								Integer.parseInt(startIp[2]),
								Integer.parseInt(startIp[3])};
		
		int [] endIpint = {Integer.parseInt(endIp[0]),
								Integer.parseInt(endIp[1]),
								Integer.parseInt(endIp[2]),
								Integer.parseInt(endIp[3])};
		
		List<IpAddress> result = new ArrayList<IpAddress>();
		int count = 1;
		for(int first = startIpint[0]; first <= endIpint[0]; first ++)
		{
			if(count > endIndex)
			{
				break;
			}
			for(int second = startIpint[1]; second <= endIpint[1]; second ++)
			{
				if(count > endIndex)
				{
					break;
				}
				for(int third = startIpint[2]; third <= endIpint[2]; third ++)
				{
					if(count > endIndex)
					{
						break;
					}
					for(int forth = startIpint[3]; forth <= endIpint[3]; forth ++)
					{
						String ip = first + "." + 
								second + "." + 
								third + "." +
								forth;
						if(!IPUtil.isPrivateIp(ip))
						{
							for(int port = 0; port < Constants.PORTS.length; port ++)
							{
								count ++;
								if(count > startIndex && count <= endIndex)
								{
									IpAddress ipAddress = new IpAddress(ip, Constants.PORTS[port], ipClass);
									result.add(ipAddress);
//									LOGGER.info(ipAddress);
								}
								else if(count > endIndex)
								{
									break;
								}
							}
						}
					}
				}
			}
		}
//		LOGGER.info("result size: " + result.size());
		return result;
	}
	
	public List<IpAddress> getRandomIpAddressList(ProxyRequest proxyRequest)
	{
		long startIpLong = 0,endIpLong = 0;
		
		int rangeSize = RandomUtil.getRandomIntNum(
							Constants.IP_RANGE_SIZE_MIN, Constants.IP_RANGE_SIZE_MAX);
		
		if(proxyRequest.getIpClass().equals(ProxyRequest.A_CLASS))
		{
			startIpLong = RandomUtil.getRandomLongNum(Constants.AClassStartIpLong, Constants.AClassEndIpLong);
			endIpLong = startIpLong + rangeSize;
			if(endIpLong > Constants.AClassEndIpLong)
				endIpLong = Constants.AClassEndIpLong;
		}
		else if(proxyRequest.getIpClass().equals(ProxyRequest.B_CLASS))
		{
			startIpLong = RandomUtil.getRandomLongNum(Constants.BClassStartIpLong, Constants.BClassEndIpLong);
			endIpLong = startIpLong + rangeSize;
			if(endIpLong > Constants.BClassEndIpLong)
				endIpLong = Constants.BClassEndIpLong;
		}
		else if(proxyRequest.getIpClass().equals(ProxyRequest.C_CLASS))
		{
			startIpLong = RandomUtil.getRandomLongNum(Constants.CClassStartIpLong, Constants.CClassEndIpLong);
			endIpLong = startIpLong + rangeSize;
			if(endIpLong > Constants.CClassEndIpLong)
				endIpLong = Constants.CClassEndIpLong;
		}
		
		List<IpAddress> result = new ArrayList<IpAddress>();
		
		for(long ipLong = startIpLong; ipLong < endIpLong; ipLong ++)
		{
			String ip = IPUtil.long2IP(ipLong);
			if(!IPUtil.isPrivateIp(ip))
			{
				for(int port = 0; port < Constants.PORTS.length; port ++)
				{
					IpAddress ipAddress = new IpAddress(ip, Constants.PORTS[port], proxyRequest.getIpClass());
					result.add(ipAddress);
//					LOGGER.info(ipAddress);
				}
			}
		}
			
		return result;
	}
	
	@Test
	public void testGetPossibleIpAddressList() throws FileNotFoundException
	{
		getPossibleIpAddressList();
	}
	
	public List<StartEndIp> getPossibleIpAddressList() throws FileNotFoundException
	{
		List<StartEndIp> result = new ArrayList<StartEndIp>();
		Scanner scanner = new Scanner(ScannerDao.class.getResourceAsStream(Constants.POSSIBLE_PROXIES_TXT_PATH));
		while(scanner.hasNext())
		{
			String line = scanner.next();
			String lineArr [] = line.split(",");
			StartEndIp startEndIp = new StartEndIp();
			startEndIp.setStartIp(lineArr[0]);
			startEndIp.setEndIp(lineArr[1]);
			LOGGER.info(startEndIp);
			result.add(startEndIp);
		}
		return result;
	}
	
	public static void main(String [] args)
	{
		String ip = "172.16.0.1";
		LOGGER.info(IPUtil.isPrivateIp(ip));
		
		ProxyRequest proxyRequest = new ProxyRequest();
		proxyRequest.setIpClass(ProxyRequest.A_CLASS);
		ScannerDao scannerDao = new ScannerDao();
		int length = 500;
		int index = 0;
		int startIndex, endIndex;
		while(true)
		{
			startIndex = length * index;
			endIndex = length * (index + 1);
			scannerDao.getIpAddressList(proxyRequest, startIndex, endIndex);
			index ++;
		}
	}

}
